package com.sk.weichat.ui.systemshare;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.v4.content.CursorLoader;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.MimeTypeMap;

import com.sk.weichat.R;
import com.sk.weichat.Reporter;
import com.sk.weichat.bean.message.ChatMessage;
import com.sk.weichat.bean.message.XmppMessage;
import com.sk.weichat.helper.DialogHelper;
import com.sk.weichat.util.LogUtils;
import com.sk.weichat.view.TipDialog;

import java.io.File;
import java.io.InputStream;
import java.net.URLDecoder;

import okio.BufferedSink;
import okio.Okio;

public class ShareUtil {

    private static Context mContext;

    /**
     * @return 初始化失败需要结束activity就返回true,
     */
    public static boolean shareInit(Activity activity, ChatMessage mShareChatMessage) {
        Intent intent = activity.getIntent();
        LogUtils.log(intent);
        if (intent == null) {
            return true;
        }
        String type = intent.getType();
        if (TextUtils.isEmpty(type)) {
            return true;
        }
        Uri stream = parseStream(intent);
        if (stream == null) {
            if (isText(intent)) {
                mShareChatMessage.setType(XmppMessage.TYPE_TEXT);
                mShareChatMessage.setContent(parseText(intent));
            }
        } else {
            if (isImage(intent)) {
                mShareChatMessage.setType(XmppMessage.TYPE_IMAGE);
            } else if (isVideo(intent)) {
                mShareChatMessage.setType(XmppMessage.TYPE_VIDEO);
            } else {
                mShareChatMessage.setType(XmppMessage.TYPE_FILE);
            }
            File file = getFileFromStream(activity, intent);

            if (file == null) {
                DialogHelper.tip(activity, activity.getString(R.string.tip_file_cache_failed));
                return true;
            }
            if (file.length() > 1024 * 1024 * 1024) {
                //文件过大
                DialogHelper.tip(activity, activity.getString(R.string.tip_share_size_too_large_supported));
                new TipDialog(mContext).setOnDismissListener(dialog -> {
                    activity.finish();
                });
            }
            mShareChatMessage.setFilePath(file.getAbsolutePath());
            mShareChatMessage.setFileSize((int) file.length());
        }
        if (mShareChatMessage.getType() == 0) {
            DialogHelper.tip(activity, activity.getString(R.string.tip_share_type_not_supported));
            new TipDialog(mContext).setOnDismissListener(dialog -> {
                activity.finish();
            });
            return true;
        }
        return false;
    }

    public static String parseText(Intent intent) {
        if (intent == null) {
            return null;
        }
        return intent.getStringExtra(Intent.EXTRA_TEXT);
    }

    public static Uri parseStream(Intent intent) {
        if (intent == null) {
            return null;
        }
        return intent.getParcelableExtra(Intent.EXTRA_STREAM);
    }

    public static File getFileFromStream(Context ctx, Intent intent) {
        mContext = ctx;
        Uri uri = parseStream(intent);
        if (uri == null) {
            return null;
        }
        String realPath = getPath(ctx, uri);
        Log.e("lzs", "realPath:" + realPath);
        String name = realPath.substring(realPath.lastIndexOf(File.separator) + 1, realPath.length());
        // 先做url decode，因为可能连路径分隔符/都被encode了，
//        try {
//            name = URLDecoder.decode(name, "UTF-8");
//            Log.e("lzs", "name1 =" + name);
//        } catch (Exception e) {
//            Reporter.unreachable(e);
//        }
//        name = name.substring(name.lastIndexOf("/") + 1);
//        Log.e("lzs", "name =" + name);
//        // 获取文件后缀名，
//        String type = intent.getType();
//        if (!TextUtils.isEmpty(type)) {
//            String ext = MimeTypeMap.getSingleton().getExtensionFromMimeType(type);
//            Log.e("lzs", "ext =" + ext);
//            if (!TextUtils.isEmpty(ext)) {
//                ext = "." + ext;
//                if (!name.endsWith(ext)) {
//                    name = name + ext;
//                }
//            }
//        }
//        Log.e("lzs", "type =" + type);
        // 转成文件File, 因为其他地方都是操作File， 只有InputStream可能无法使用，
        try {
            // TODO: 缓存可能多余，而且在主线程多少导致白屏，
            File cacheFolder = new File(ctx.getCacheDir(), "SystemShare");
            if (!cacheFolder.exists()) {
                cacheFolder.mkdirs();
            }
            File cacheFile = new File(cacheFolder, name);
            InputStream input = ctx.getContentResolver().openInputStream(uri);
            BufferedSink buffer = Okio.buffer(Okio.sink(cacheFile));
            buffer.writeAll(Okio.source(input));
            buffer.flush();
            buffer.close();
            return cacheFile;
        } catch (Exception e) {
            Reporter.unreachable(e);
            return null;
        }
    }

    public static String getFilePathFromStream(Context ctx, Intent intent) {
        File file = getFileFromStream(ctx, intent);
        if (file == null) {
            return null;
        }
        return file.getPath();
    }

    /**
     * 判断是否是分享文字，不包括分享txt文件的情况，
     */
    public static boolean isText(Intent intent) {
        return checkType(intent, "text")
                && !TextUtils.isEmpty(parseText(intent));
    }

    public static boolean isImage(Intent intent) {
        return isFile(intent)
                && checkType(intent, "image");
    }

    public static boolean isVideo(Intent intent) {
        return isFile(intent)
                && checkType(intent, "video");
    }

    public static boolean isFile(Intent intent) {
        return parseStream(intent) != null;
    }

    private static boolean checkType(Intent intent, String prefix) {
        if (intent == null) {
            return false;
        }
        String type = intent.getType();
        if (TextUtils.isEmpty(type)) {
            return false;
        }
        return type.startsWith(prefix);
    }


    public static String getPath(final Context context, final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;

                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

}
